<script setup lang="ts">

import {useAppStore, useDictStore} from "@/stores";
import {taskApi} from "@/api/task";
import type {SysTask} from "@/api/task/types.ts";
import {
  DataTableBaseColumn,
  DataTableColumns,
  DataTableFilterState,
  DataTableInst,
  NButton,
  NButtonGroup,
  PaginationInfo,
  PaginationProps
} from "naive-ui";
import {renderPermission, resetToNull} from "@/utils";

interface PageQuery {
  keyword: string,
  taskStatus: number,
  dateTimeRange: [string, string]
}

const appStore = useAppStore();
const dictStore = useDictStore();
const pageQuery = reactive<PageQuery>(<PageQuery>{})
const tableLoading = ref(false);
const tableRef = ref<DataTableInst | null>(null)
const tableColumns = ref<DataTableColumns<SysTask>>([
  {title: '任务编码', key: 'taskCode', resizable: true},
  {title: '任务名称', key: 'taskName', resizable: true},
  {
    title: '执行类型',
    key: 'executeType',
    resizable: true,
    render: row => dictStore.renderTag('task-execute-type', row.executeType),
    filter: true,
    filterMultiple: false,
    filterOptions: dictStore.getDictTextOptions('task-execute-type')
  },
  {title: '计划时间', key: 'scheduleTime', resizable: true},
  {title: '执行时间', key: 'executeTime', resizable: true},
  {
    title: '任务状态',
    key: 'taskStatus',
    resizable: true,
    render: row => dictStore.renderTag('task-status', row.taskStatus),
    filter: true,
    filterMultiple: false,
    filterOptions: dictStore.getDictTextOptions('task-status')
  },
  {title: '操作', key: 'action', align: 'center', render: row => tableActionRender(row)}
])
const tableData = ref<SysTask[]>([])
const tablePagination = reactive<PaginationProps>({
  prefix: (info: PaginationInfo) => {
    return `共 ${info.itemCount} 条记录`
  },
  showSizePicker: true,
  pageSizes: [10, 20, 50, 100],
  itemCount: 0,
  pageCount: 0,
  onChange: (page: number) => {
    tablePagination.page = page
    handlePageQuery()
  },
  onUpdatePageSize: (pageSize: number) => {
    tablePagination.pageSize = pageSize
    tablePagination.page = 1
    handlePageQuery()
  }
})

const drawerDetailShow = ref(false)
const drawerDetailFormModel = reactive<SysTask>(<SysTask>{})

onMounted(() => {
  dictStore.loadDict(['task-execute-type', 'task-status'])
  handlePageQuery()
})

const tableActionRender = (row: SysTask) => {
  return h(NButtonGroup, {size: 'small'}, {
    default: () => {
      return [
        renderPermission(h(NButton, {
          tertiary: true,
          type: 'primary',
          onClick: () => handleClickDetail(row)
        }, {default: () => '详情'}), 'task:detail'),
      ]
    }
  })
}

const handlePageQuery = () => {
  tableLoading.value = true
  const {dateTimeRange, ...rest} = pageQuery
  taskApi.page({
    ...rest,
    startTime: dateTimeRange?.[0],
    endTime: dateTimeRange?.[1],
    current: tablePagination.page ?? 1,
    size: tablePagination.pageSize ?? 10
  }).then(res => {
    tableData.value = res.data.records
    tablePagination.itemCount = res.data.total
    tablePagination.pageCount = res.data.pages
  }).finally(() => tableLoading.value = false)
}
const handleClickReset = () => {
  resetToNull(pageQuery)
  tableRef.value?.filter(null)
  handlePageQuery()
}
const handleClickDetail = (row: SysTask) => {
  if (row.id) {
    taskApi.detail(row.id).then(res => {
      Object.assign(drawerDetailFormModel, res.data)
      drawerDetailShow.value = true
    })
  }
}
const handleDrawerClose = () => {
  drawerDetailShow.value = false
  resetToNull(drawerDetailFormModel)
  handlePageQuery()
}
</script>
<template>
  <n-card class="task-center">
    <template #header>
      <n-space>
        <n-input v-model:value="pageQuery.keyword" placeholder="任务名称/任务编码" clearable></n-input>
        <n-date-picker
            clearable
            v-model:formatted-value="pageQuery.dateTimeRange"
            type="daterange"
            value-format="yyyy-MM-dd"
        />
        <n-button
            secondary
            @click="handlePageQuery"
            :loading="tableLoading"
            v-p="'task:page'"
        >查询
        </n-button>
        <n-button
            secondary
            type="warning"
            @click="handleClickReset"
        >重置
        </n-button>
      </n-space>
    </template>
    <n-data-table
        remote
        ref="tableRef"
        :loading="tableLoading"
        :columns="tableColumns"
        :data="tableData"
        :pagination="tablePagination"
        @update:filters="(filters: DataTableFilterState, {key}: DataTableBaseColumn) => {
          pageQuery[key] = filters[key]
          handlePageQuery()
        }"
    />
  </n-card>
  <n-drawer
      v-model:show="drawerDetailShow"
      :width="600"
      placement="right"
      :on-after-leave="handleDrawerClose"
      :auto-focus="false"
      :mask-closable="false"
      close-on-esc
  >
    <n-drawer-content
        title="任务详情"
        closable
    >
      <n-descriptions
          :columns="2"
          bordered
      >
        <n-descriptions-item label="任务编码" :span="1">{{ drawerDetailFormModel.taskCode }}</n-descriptions-item>
        <n-descriptions-item label="任务名称" :span="1">{{ drawerDetailFormModel.taskName }}</n-descriptions-item>
        <n-descriptions-item label="执行类型" :span="1">
          <dict-tag dict-code="task-execute-type" :dict-value="drawerDetailFormModel.executeType"/>
        </n-descriptions-item>
        <n-descriptions-item label="任务状态" :span="1">
          <dict-tag dict-code="task-status" :dict-value="drawerDetailFormModel.taskStatus"/>
        </n-descriptions-item>
        <n-descriptions-item label="计划时间" :span="1">{{ drawerDetailFormModel.scheduleTime }}</n-descriptions-item>
        <n-descriptions-item label="执行时间" :span="1">{{ drawerDetailFormModel.executeTime }}</n-descriptions-item>
        <n-descriptions-item label="阻塞策略" :span="2">{{ drawerDetailFormModel.executeBlockStrategy }}
        </n-descriptions-item>
        <n-descriptions-item label="任务参数" :span="2">
          <vue-json-pretty
              :theme="appStore.darkTheme ? 'dark' : 'light'"
              :data="JSON.parse(drawerDetailFormModel.taskParam||'')"
              show-length
              :deep="1"
          />
        </n-descriptions-item>
        <n-descriptions-item v-if="drawerDetailFormModel.taskStatus === 3" label="错误信息">
          <n-text>{{ drawerDetailFormModel.errorMessage || '无信息' }}</n-text>
        </n-descriptions-item>
      </n-descriptions>
    </n-drawer-content>
  </n-drawer>
</template>
<style scoped>
</style>
